#include "stdafx.h"
#include "net/ServerSocket.hpp"
#include "net/ServerSocketImpl.hpp"

NET_NAMESPACE_BEGIN

CServerSocket::CServerSocket() : CSocket(new CServerSocketImpl)
{
}

CServerSocket::CServerSocket(const CSocket& socket) : CSocket(socket)
{
	if (!dynamic_cast<CServerSocketImpl*>(impl()))
		throw InvalidArgumentException("Cannot assign incompatible socket");
}

CServerSocket::CServerSocket(const CSocketAddress& address, int backlog) : CSocket(new CServerSocketImpl)
{
	impl()->bind(address, true);
	impl()->listen(backlog);
}

CServerSocket::CServerSocket(UInt16 port, int backlog) : CSocket(new CServerSocketImpl)
{
	CIPAddress wildcardAddr;
	CSocketAddress address(wildcardAddr, port);
	impl()->bind(address, true);
	impl()->listen(backlog);
}

CServerSocket::CServerSocket(CSocketImpl* pImpl, bool ignore) : CSocket(pImpl)
{
}

CServerSocket::~CServerSocket()
{
}

CServerSocket& CServerSocket::operator = (const CSocket& socket)
{
	if (dynamic_cast<CServerSocketImpl*>(socket.impl()))
		CSocket::operator = (socket);
	else
		throw InvalidArgumentException("Cannot assign incompatible socket");
	return *this;
}

void CServerSocket::bind(const CSocketAddress& address, bool reuseAddress)
{
	impl()->bind(address, reuseAddress);
}

void CServerSocket::bind(UInt16 port, bool reuseAddress)
{
	CIPAddress wildcardAddr;
	CSocketAddress address(wildcardAddr, port);
	impl()->bind(address, reuseAddress);
}

void CServerSocket::bind6(const CSocketAddress& address, bool reuseAddress, bool ipV6Only)
{
	impl()->bind6(address, reuseAddress, ipV6Only);
}

void CServerSocket::bind6(UInt16 port, bool reuseAddress, bool ipV6Only)
{
	CIPAddress wildcardAddr(CIPAddress::IPv6);
	CSocketAddress address(wildcardAddr, port);
	impl()->bind6(address, reuseAddress, ipV6Only);
}

void CServerSocket::listen(int backlog)
{
	impl()->listen(backlog);
}

CStreamSocket CServerSocket::acceptConnection(CSocketAddress& clientAddr)
{
	return CStreamSocket(impl()->acceptConnection(clientAddr));
}

CStreamSocket CServerSocket::acceptConnection()
{
	CSocketAddress clientAddr;
	return CStreamSocket(impl()->acceptConnection(clientAddr));
}

NET_NAMESPACE_END
